// ==++==
// 
//   
//    Copyright (c) 2006 Microsoft Corporation.  All rights reserved.
//   
//    The use and distribution terms for this software are contained in the file
//    named license.txt, which can be found in the root of this distribution.
//    By using this software in any fashion, you are agreeing to be bound by the
//    terms of this license.
//   
//    You must not remove this notice, or any other, from this software.
//   
// 
// ==--==

// This tool generates the unicode_data.c file which contains the unicode data table

#include <ctype.h>
#include <stdio.h> 
#include <windows.h> 

CONST char copyright_header[] = 
    "// ==++==\n"
    "// \n"
    "//   Copyright (c) Microsoft Corporation.  All rights reserved.\n"
    "// \n"
    "// ==--==\n"
    "\n"
    "// This file is generated by rotor/tools/genpalunitable.\n"
    "\n"
    "#include \"pal/unicode_data.h\"\n"
    "\n"
    "CONST UnicodeDataRec UnicodeData[] =\n"
    "{\n";

/* If we need the description of unicode chars in unicode_data.c, then we just
   have to set UnicodeDataStrings table with all wchars description strings */
char* UnicodeDataStrings[] = {""};

int __cdecl main(int argc, char *argv[])
{    
    FILE *fpOut;
    WORD Info, 
         InfoOut = 0xFFFF,
         duplicate = 0, 
         i,
         iOut = 0xFFFF;

    WCHAR oppC = 0, 
          oppCout = 0xFFFF;
    CONST UINT LAST_DIRECT_ACCESS = 256;

    if (!(fpOut = fopen("unicode_data.c", "w")))
    {
        printf("Unable to open unicode_data.c for write\n");
        return 1;
    }

    fprintf(fpOut, "%s", copyright_header);

    for (i=0; i < 0xFFFF; i++)
    {        
        if (!GetStringTypeExW(LOCALE_USER_DEFAULT, CT_CTYPE1, 
            (WCHAR*)&i, 1, &Info))
        {
            fprintf(fpOut, 
                "GetStringTypeExW failed to get information for %#X!\n", i);
            return 1;
        }
        
        oppC = iswupper(i) ? towlower(i) : (iswlower(i) ? towupper(i) : 0);
        
        /* Print out all 256 first chars */
        if (i <= LAST_DIRECT_ACCESS)
        {
            fprintf(fpOut, "{ 0x%04x,\t0x%04x,\t0x%04x,\t%d },\t\t%s\n", 
                    i, Info, oppC, 0, UnicodeDataStrings[/*i*/0]);
        }
        else
        {
            if ((oppC != 0) || (Info != 0))        
            {
                /* We don't need to print out all chars with the same C1_TYPE 
                   and with the same opposite char */
                if ((oppC == oppCout) && (Info == InfoOut))
                {
                    duplicate ++;
                    fprintf(fpOut, "/*0x%04x,\t0x%04x,\t0x%04x,\t%d } */\t\t%s\n", 
                            i, Info, oppC, 0, UnicodeDataStrings[/*i*/ 0]);

                }
                else
                {
                    if (iOut != 0xFFFF)
                    {
                        fprintf(fpOut, "{ 0x%04x,\t0x%04x,\t0x%04x,\t%d },"
                                "\t\t%s\n", iOut, InfoOut, oppCout, duplicate,
                                UnicodeDataStrings[/*iOut*/ 0]);
                    }

                    /* reset the next char to print out */
                    InfoOut = Info;
                    oppCout = oppC;
                    duplicate = 0;                        
                    iOut = i;
                }
            }
            else
            {
                fprintf(fpOut, "/*0x%04x,\t0x%04x,\t0x%04x,\t%d } */\t\t%s\n", 
                        i, Info, oppC, 0, UnicodeDataStrings[/*i*/0]);
            }

        }
    }
    
    fprintf(fpOut, "};\n\n");
    fprintf(fpOut, "CONST UINT UNICODE_DATA_SIZE = "
            "sizeof(UnicodeData)/sizeof(UnicodeDataRec);\n");
    fprintf(fpOut, "CONST UINT UNICODE_DATA_DIRECT_ACCESS = %d;\n", 
            LAST_DIRECT_ACCESS);
    
    fclose(fpOut);
    
    return 0;
}
